package com.ts.api.module.app.user.controller;

import com.gitee.apanlh.annotation.viewresolver.RequestParamVo;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.reflection.CopyUtils;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.util.valid.IdcardUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.gitee.apanlh.web.model.vo.RequestVO;
import com.gitee.apanlh.web.model.vo.ResultVO;
import com.ts.api.common.constant.BizEnum;
import com.ts.api.common.constant.app.AppBizCodeEnum;
import com.ts.api.common.constant.channel.ChannelUserStatus;
import com.ts.api.common.context.ChannelUserContext;
import com.ts.api.common.localcache.DistrictCache;
import com.ts.api.common.redis.UserRedisKey;
import com.ts.api.exp.BizException;
import com.ts.api.module.app.user.entity.AppUserPO;
import com.ts.api.module.app.user.entity.vo.RespAppUserVO;
import com.ts.api.module.app.user.entity.vo.RespLoginVO;
import com.ts.api.module.channel.entity.bo.ChannelRegisterFieldBO;
import com.ts.api.module.channel.entity.bo.ChannelUserBO;
import com.ts.api.module.channel.entity.cache.ChannelCacheUser;
import com.ts.api.module.channel.entity.po.ChannelUserFormFieldPO;
import com.ts.api.module.channel.entity.po.ChannelUserRegisterPO;
import com.ts.api.module.channel.entity.qo.ChannelUserFormMappingQO;
import com.ts.api.module.channel.entity.qo.ChannelUserQO;
import com.ts.api.module.channel.service.ChannelFormService;
import com.ts.api.module.channel.service.ChannelLoginService;
import com.ts.api.module.channel.service.ChannelUserService;
import com.ts.api.module.channel.service.DoubleWriteUserService;
import com.ts.api.module.common.entity.DistrictPO;
import com.ts.api.module.common.service.SmsService;
import com.ts.api.module.common.service.UserRealAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 *  AppLogin
 *
 *  @author Pan
 */
@RestController
@RequestMapping("/app/user")
public class AppUserController {

    @Autowired
    private ChannelUserService channelUserService;
    @Autowired
    private ChannelLoginService loginService;
    @Autowired
    private ChannelFormService channelFormService;
    @Autowired
    private UserRealAuthService userRealAuthService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private DoubleWriteUserService doubleWriteUserService;

    /**
     *  用户登录注册接口
     *
     *  @param  requestVO
     *  @return ResultVO
     */
    @PostMapping("/login")
    public ResultVO<Object> login(@RequestParamVo RequestVO requestVO) {
        String phone = requestVO.get("phone", String.class);
        String code = requestVO.get("code", String.class);
        if (!ValidParam.required(phone, code)) {
            throw new BizException(BizEnum.EMPTY);
        }

        if (phone.length() != 11) {
            return ResultVO.fail("请输入正确的手机号");
        }

        //  短信验证码
        smsService.validSmsCode(phone, code);

        //  注册
        ChannelRegisterFieldBO channelRegisterFieldBO = new ChannelRegisterFieldBO();
        channelRegisterFieldBO.put("phone", phone);

        ChannelUserBO userFlowBO = channelUserService.register(code, channelRegisterFieldBO, false);
        String token = loginService.createToken(ChannelCacheUser.create(userFlowBO.getUserId(), userFlowBO.getPhone()));
        //  返回token
        return ResultVO.suc(new RespLoginVO(token));
    }

    /**
     *  用户退出接口
     *
     *  @return ResultVO
     */
    @PostMapping("/logout")
    public ResultVO<Object> logout() {
        //  删除token
        UserRedisKey.LOGIN_TOKEN.delKey(ChannelUserContext.get().getPhone());
        return ResultVO.suc("退出成功");
    }

    /**
     *  用户注销接口
     *
     *  @return ResultVO
     */
    @PostMapping("/cancel")
    public ResultVO<Object> cancel() {
        ChannelUserRegisterPO userRegisterPO = new ChannelUserRegisterPO();
        userRegisterPO.setId(ChannelUserContext.getId());
        userRegisterPO.setStatus(ChannelUserStatus.CANCEL.getStatus());
        doubleWriteUserService.updateUser(userRegisterPO);

        //  删除token
        UserRedisKey.LOGIN_TOKEN.delKey(ChannelUserContext.get().getPhone());
        return ResultVO.suc("注销成功");
    }

    /**
     *  更新用户接口
     *
     *  @param  requestVO
     *  @return ResultVO
     */
    @PostMapping("/update")
    public ResultVO<Object> update(@RequestParamVo RequestVO requestVO) {
        AppUserPO appUserPO = requestVO.toBean(AppUserPO.class);
        Assert.isNotNullThrows(appUserPO, new BizException(BizEnum.EMPTY));
        ChannelUserRegisterPO userRegisterPO = CopyUtils.copy(appUserPO, ChannelUserRegisterPO.class);
        userRegisterPO.setId(ChannelUserContext.getId());

        //  前端传的城市名称有可能是简写，要转一下，避免分发的时候造成问题
        DistrictPO districtPO = DistrictCache.getByName(userRegisterPO.getAreaName());
        userRegisterPO.setAreaCode(districtPO.getCode());
        userRegisterPO.setAreaName(districtPO.getName());

        doubleWriteUserService.updateUser(userRegisterPO);
        return ResultVO.suc();
    }

    /**
     *  获取用户信息个人接口
     *
     *  @return ResultVO
     */
    @GetMapping("/get")
    public ResultVO<Object> get() {
        ChannelCacheUser cacheUser = ChannelUserContext.get();
        ChannelUserRegisterPO channelUserRegisterPO = channelUserService.get(ChannelUserQO.createPhone(cacheUser.getPhone()));
        return ResultVO.suc(CopyUtils.copy(channelUserRegisterPO, RespAppUserVO.class));
    }

    /**
     *  获取用户已填写的表单信息
     *
     *  @return ResultVO
     */
    @GetMapping("/getForm")
    public ResultVO<Object> getForm(@RequestParamVo RequestVO requestVO) {
        String bizCode = requestVO.get("bizCode", String.class);
        if (ValidParam.isEmpty(bizCode)) {
            return ResultVO.suc(channelFormService.listUserFormField());
        }

        //  大额贷特殊用户表单信息
        AppBizCodeEnum appBizCodeEnum = AppBizCodeEnum.getByCode(bizCode);
        if (Eq.enums(appBizCodeEnum, AppBizCodeEnum.ESD_LARGE_LOAN)) {
            // 过滤数据
            List<ChannelUserFormFieldPO> listResp = CollUtils.newArrayList();

            ChannelUserFormMappingQO channelUserFormMappingQO = new ChannelUserFormMappingQO();
            channelUserFormMappingQO.setUserId(ChannelUserContext.getId());
            //  只获取这四个字段
            channelUserFormMappingQO.setListMapping(CollUtils.newArrayList("sesameCredit", "overdue", "monthlySalary", "loanAmount"));
            //  这里返回的fieldValueId是用户选中的fieldValueId
            List<ChannelUserFormFieldPO> listChannelUserFormFieldPO = channelFormService.listFieldByMappingNameAndUser(channelUserFormMappingQO);

            Map<String, List<ChannelUserFormFieldPO>> map = CollUtils.groupByToLinked(listChannelUserFormFieldPO, t -> t.getFieldName());
            IteratorUtils.entrySet(map, (k, v) -> {
                ChannelUserFormFieldPO channelUserFormFieldPO = v.get(0);
                //  获取当前用户选中的值
                Long userFormFieldValueId = channelUserFormFieldPO.getUserFormFieldValueId();

                //  找到正确的值
                if (ValidParam.isNotNull(userFormFieldValueId)) {
                    int indexOf = CollUtils.indexOf(v, t2 -> t2.getFormFieldValueId().equals(userFormFieldValueId));
                    listResp.add(v.get(indexOf));
                    return ;
                }
                listResp.add(channelUserFormFieldPO);
            });
            return ResultVO.suc(listResp);
        }
        return ResultVO.suc();
    }

    /**
     *  用户实名认证
     *
     *  @param  requestVO
     *  @return ResultVO
     */
    @PostMapping("/real/valid")
    public ResultVO<Object> realValid(@RequestParamVo RequestVO requestVO) {
        String userName = requestVO.get("userName", String.class);
        String idcard = requestVO.get("idcard", String.class);
        if (!ValidParam.required(userName, idcard)) {
            throw new BizException(BizEnum.EMPTY);
        }

        //  基础验证
        boolean valid = IdcardUtils.valid(idcard);
        if (!valid) {
            return ResultVO.fail("认证失败,请输入正确的身份证");
        }

        Boolean nameAndIdcardFlag = userRealAuthService.nameAndIdcard(userName, idcard);
        if (!nameAndIdcardFlag) {
            return ResultVO.fail("认证失败,请输入正确的信息");
        }

        ChannelUserRegisterPO userRegisterPO = new ChannelUserRegisterPO();
        userRegisterPO.setId(ChannelUserContext.getId());
        userRegisterPO.setUserName(userName);
        userRegisterPO.setIdcard(idcard);
        doubleWriteUserService.updateUser(userRegisterPO);
        return ResultVO.suc("认证成功");
    }
}
